/**
 * @file DR16.cpp
 * @author yssickjgd (1345578933@qq.com)
 * @brief DR16遥控器
 * @version 0.1
 * @date 2022-05-26
 *
 * @copyright USTC-RoboWalker (c) 2022
 *
 */

/* Includes ------------------------------------------------------------------*/

#include "dvc_dr16.h"

/* Private macros ------------------------------------------------------------*/

/* Private types -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function declarations ---------------------------------------------*/

/**
 * @brief 遥控器DR16初始化
 *
 * @param __huart 指定的UART
 */
void Class_DR16::Init(UART_HandleTypeDef *__huart)
{
    huart = __huart;
    if (huart->Instance == USART1)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART1_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == USART2)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART2_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == USART3)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART3_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == UART4)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART4_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == UART5)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART5_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == USART6)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART6_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == UART7)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART7_Manage_Object.Rx_Buffer;
    }
    else if (huart->Instance == UART8)
    {
        UART_Rx_Data = (Struct_DR16_UART_Data *)UART8_Manage_Object.Rx_Buffer;
    }
}
/**
 * @brief 重置接收数据
 *
 */
void Class_DR16::Reset_UART_Rx_Data()
{
    UART_Rx_Data->Channel_0 = 1024;
    UART_Rx_Data->Channel_1 = 1024;
    UART_Rx_Data->Channel_2 = 1024;
    UART_Rx_Data->Channel_3 = 1024;
    UART_Rx_Data->Switch_2 = SWITCH_MIDDLE;
    UART_Rx_Data->Switch_1 = SWITCH_DOWN;
    UART_Rx_Data->Mouse_X = 0;
    UART_Rx_Data->Mouse_Y = 0;
    UART_Rx_Data->Mouse_Z = 0;
    UART_Rx_Data->Mouse_Left_Key = 0;
    UART_Rx_Data->Mouse_Right_Key = 0;
    UART_Rx_Data->Keyboard_Key = 0;
    UART_Rx_Data->Channel_Yaw = 1024;
}

/**
 * @brief 判断拨动开关状态
 *
 */
void Class_DR16::Judge_Switch(Enum_DR16_Switch_Status *Switch, uint8_t Status, uint8_t Pre_Status)
{
    switch (Pre_Status)
    {
    case (SWITCH_UP):
    {
        switch (Status)
        {
        case (SWITCH_UP):
        {
            *Switch = DR16_Switch_Status_UP;
        }
        break;
        case (SWITCH_DOWN):
        {
            *Switch = DR16_Switch_Status_TRIG_MIDDLE_DOWN;
        }
        break;
        case (SWITCH_MIDDLE):
        {
            *Switch = DR16_Switch_Status_TRIG_UP_MIDDLE;
        }
        break;
        }
    }
    break;
    case (SWITCH_DOWN):
    {
        switch (Status)
        {
        case (SWITCH_UP):
        {
            *Switch = DR16_Switch_Status_TRIG_MIDDLE_UP;
        }
        break;
        case (SWITCH_DOWN):
        {
            *Switch = DR16_Switch_Status_DOWN;
        }
        break;
        case (SWITCH_MIDDLE):
        {
            *Switch = DR16_Switch_Status_TRIG_DOWN_MIDDLE;
        }
        break;
        }
    }
    break;
    case (SWITCH_MIDDLE):
    {
        switch (Status)
        {
        case (SWITCH_UP):
        {
            *Switch = DR16_Switch_Status_TRIG_MIDDLE_UP;
        }
        break;
        case (SWITCH_DOWN):
        {
            *Switch = DR16_Switch_Status_TRIG_MIDDLE_DOWN;
        }
        break;
        case (SWITCH_MIDDLE):
        {
            *Switch = DR16_Switch_Status_MIDDLE;
        }
        break;
        }
    }
    break;
    }
}

/**
 * @brief 判断按键状态
 *
 */
void Class_DR16::Judge_Key(Enum_DR16_Key_Status *Key, uint8_t Status, uint8_t Pre_Status)
{
    switch (Pre_Status)
    {
    case (KEY_FREE):
    {
        switch (Status)
        {
        case (KEY_FREE):
        {
            *Key = DR16_Key_Status_FREE;
        }
        break;
        case (KEY_PRESSED):
        {
            *Key = DR16_Key_Status_TRIG_FREE_PRESSED;
        }
        break;
        }
    }
    break;
    case (KEY_PRESSED):
    {
        switch (Status)
        {
        case (KEY_FREE):
        {
            *Key = DR16_Key_Status_TRIG_PRESSED_FREE;
        }
        break;
        case (KEY_PRESSED):
        {
            *Key = DR16_Key_Status_PRESSED;
        }
        break;
        }
    }
    break;
    }
}

/**
 * @brief 数据处理过程
 *
 */
void Class_DR16::Data_Process()
{

    //数据处理过程
    Data.Right_X = (UART_Rx_Data->Channel_0 - 1024.0f) / 660.0f;
    Data.Right_Y = (UART_Rx_Data->Channel_1 - 1024.0f) / 660.0f;
    Data.Left_X = (UART_Rx_Data->Channel_2 - 1024.0f) / 660.0f;
    Data.Left_Y = (UART_Rx_Data->Channel_3 - 1024.0f) / 660.0f;

    Judge_Switch(&Data.Left_Switch, UART_Rx_Data->Switch_1, Pre_UART_Rx_Data.Switch_1);
    Judge_Switch(&Data.Right_Switch, UART_Rx_Data->Switch_2, Pre_UART_Rx_Data.Switch_2);

    Data.Mouse_X = UART_Rx_Data->Mouse_X / 32768.0f;
    Data.Mouse_Y = UART_Rx_Data->Mouse_Y / 32768.0f;
    Data.Mouse_Z = UART_Rx_Data->Mouse_Z / 32768.0f;

    Judge_Key(&Data.Mouse_Left_Key, UART_Rx_Data->Mouse_Left_Key, Pre_UART_Rx_Data.Mouse_Left_Key);
    Judge_Key(&Data.Mouse_Right_Key, UART_Rx_Data->Mouse_Right_Key, Pre_UART_Rx_Data.Mouse_Right_Key);
    for (int i = 0; i < 16; i++)
    {
        Judge_Key(&Data.Keyboard_Key[i], ((UART_Rx_Data->Keyboard_Key) >> i) & 0x1, ((Pre_UART_Rx_Data.Keyboard_Key) >> i) & 0x1);
    }

    Data.Yaw = (UART_Rx_Data->Channel_Yaw - 1024.0f) / 660.0f;
}

/**
 * @brief 获取遥控器在线状态
 *
 * @return Enum_DR16_Status 遥控器在线状态
 */
Enum_DR16_Status Class_DR16::Get_DR16_Status()
{
    return (DR16_Status);
}

/**
 * @brief 获取遥控器右侧x轴摇杆状态
 *
 * @return float 遥控器右侧x轴摇杆状态
 */
float Class_DR16::Get_Right_X()
{
    return (Data.Right_X);
}

/**
 * @brief 获取遥控器右侧y轴摇杆状态
 *
 * @return float 遥控器右侧y轴摇杆状态
 */
float Class_DR16::Get_Right_Y()
{
    return (Data.Right_Y);
}

/**
 * @brief 获取遥控器左侧x轴摇杆状态
 *
 * @return float 遥控器左侧x轴摇杆状态
 */
float Class_DR16::Get_Left_X()
{
    return (Data.Left_X);
}

/**
 * @brief 获取遥控器左侧y轴摇杆状态
 *
 * @return float 遥控器左侧y轴摇杆状态
 */
float Class_DR16::Get_Left_Y()
{
    return (Data.Left_Y);
}

/**
 * @brief 获取遥控器左侧拨动开关状态
 *
 * @return Enum_DR16_Switch_Status 遥控器左侧拨动开关状态
 */
Enum_DR16_Switch_Status Class_DR16::Get_Left_Switch()
{
    return (Data.Left_Switch);
}

/**
 * @brief 获取遥控器右侧拨动开关状态
 *
 * @return Enum_DR16_Switch_Status 遥控器右侧拨动开关状态
 */
Enum_DR16_Switch_Status Class_DR16::Get_Right_Switch()
{
    return (Data.Right_Switch);
}

/**
 * @brief 获取鼠标x轴状态
 *
 * @return float 鼠标x轴状态
 */
float Class_DR16::Get_Mouse_X()
{
    return (Data.Mouse_X);
}

/**
 * @brief 获取鼠标y轴状态
 *
 * @return float 鼠标y轴状态
 */
float Class_DR16::Get_Mouse_Y()
{
    return (Data.Mouse_Y);
}

/**
 * @brief 获取鼠标z轴状态
 *
 * @return float 鼠标z轴状态
 */
float Class_DR16::Get_Mouse_Z()
{
    return (Data.Mouse_Z);
}

/**
 * @brief 获取鼠标左键状态
 *
 * @return Enum_DR16_Key_Status 鼠标左键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Mouse_Left_Key()
{
    return (Data.Mouse_Left_Key);
}

/**
 * @brief 获取鼠标右键状态
 *
 * @return Enum_DR16_Key_Status 鼠标右键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Mouse_Right_Key()
{
    return (Data.Mouse_Right_Key);
}

/**
 * @brief 获取键盘W键状态
 *
 * @return Enum_DR16_Key_Status 键盘W键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_W()
{
    return (Data.Keyboard_Key[KEY_W]);
}

/**
 * @brief 获取键盘S键状态
 *
 * @return Enum_DR16_Key_Status 键盘S键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_S()
{
    return (Data.Keyboard_Key[KEY_S]);
}

/**
 * @brief 获取键盘A键状态
 *
 * @return Enum_DR16_Key_Status 键盘A键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_A()
{
    return (Data.Keyboard_Key[KEY_A]);
}

/**
 * @brief 获取键盘D键状态
 *
 * @return Enum_DR16_Key_Status 键盘D键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_D()
{
    return (Data.Keyboard_Key[KEY_D]);
}

/**
 * @brief 获取键盘Shift键状态
 *
 * @return Enum_DR16_Key_Status 键盘Shift键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_Shift()
{
    return (Data.Keyboard_Key[KEY_SHIFT]);
}

/**
 * @brief 获取键盘Ctrl键状态
 *
 * @return Enum_DR16_Key_Status 键盘Ctrl键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_Ctrl()
{
    return (Data.Keyboard_Key[KEY_CTRL]);
}

/**
 * @brief 获取键盘Q键状态
 *
 * @return Enum_DR16_Key_Status 键盘Q键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_Q()
{
    return (Data.Keyboard_Key[KEY_Q]);
}

/**
 * @brief 获取键盘E键状态
 *
 * @return Enum_DR16_Key_Status 键盘E键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_E()
{
    return (Data.Keyboard_Key[KEY_E]);
}

/**
 * @brief 获取键盘R键状态
 *
 * @return Enum_DR16_Key_Status 键盘R键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_R()
{
    return (Data.Keyboard_Key[KEY_R]);
}

/**
 * @brief 获取键盘F键状态
 *
 * @return Enum_DR16_Key_Status 键盘F键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_F()
{
    return (Data.Keyboard_Key[KEY_F]);
}

/**
 * @brief 获取键盘G键状态
 *
 * @return Enum_DR16_Key_Status 键盘G键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_G()
{
    return (Data.Keyboard_Key[KEY_G]);
}

/**
 * @brief 获取键盘Z键状态
 *
 * @return Enum_DR16_Key_Status 键盘Z键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_Z()
{
    return (Data.Keyboard_Key[KEY_Z]);
}

/**
 * @brief 获取键盘X键状态
 *
 * @return Enum_DR16_Key_Status 键盘X键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_X()
{
    return (Data.Keyboard_Key[KEY_X]);
}

/**
 * @brief 获取键盘C键状态
 *
 * @return Enum_DR16_Key_Status 键盘C键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_C()
{
    return (Data.Keyboard_Key[KEY_C]);
}

/**
 * @brief 获取键盘V键状态
 *
 * @return Enum_DR16_Key_Status 键盘V键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_V()
{
    return (Data.Keyboard_Key[KEY_V]);
}

/**
 * @brief 获取键盘B键状态
 *
 * @return Enum_DR16_Key_Status 键盘B键状态
 */
Enum_DR16_Key_Status Class_DR16::Get_Keyboard_Key_B()
{
    return (Data.Keyboard_Key[KEY_B]);
}

/**
 * @brief 获取遥控器yaw轴状态
 *
 * @return float 遥控器yaw轴状态
 */
float Class_DR16::Get_Yaw()
{
    return (Data.Yaw);
}

/**
 * @brief TIM定时器中断定期检测遥控器是否存活
 *
 */
void Class_DR16::TIM_Alive_PeriodElapsedCallback()
{
    //判断该时间段内是否接收过遥控器数据
    if (Flag == Pre_Flag)
    {
        //遥控器断开连接
        DR16_Status = DR16_Status_DISABLE;
        Reset_UART_Rx_Data();
        Data_Process();
    }
    else
    {
        //遥控器保持连接
        DR16_Status = DR16_Status_ENABLE;
    }
    Pre_Flag = Flag;
}

/**
 * @brief UART通信接收回调函数
 *
 * @param Rx_Data 接收的数据
 */
void Class_DR16::UART_RxCpltCallback(uint8_t *Rx_Data)
{
    //滑动窗口, 判断遥控器是否在线
    Flag += 1;

    Data_Process();

    //保留数据
    memcpy(&Pre_UART_Rx_Data, UART_Rx_Data, 18 * sizeof(uint8_t));
}

/* Function prototypes -------------------------------------------------------*/

/************************ COPYRIGHT(C) USTC-ROBOWALKER **************************/
